package com.bodu.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.bodu.core.entity.ParamReq;
import com.bodu.core.entity.result.Result;
import com.bodu.system.entity.po.CodeGenConfigPo;
import com.bodu.system.entity.po.CodeGenPo;
import com.bodu.system.entity.request.CodeGenRequest;
import com.bodu.system.entity.vo.CodeGenVo;
import com.bodu.system.mapper.CodeGenConfigMapper;
import com.bodu.system.mapper.CodeGenMapper;
import com.bodu.system.service.CodeGenService;
import com.bodu.system.template.filetemplate.TemplateFactory;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @author Administrator
 */
@Service
public class CodeGenServiceImpl implements CodeGenService {

    @Resource
    private CodeGenMapper codeGenMapper;

    @Resource
    private CodeGenConfigMapper codeGenConfigMapper;

    private final TemplateFactory templateFactory;

    /**
     * 生成代码生成配置ID
     */
    private final static Long CODE_GEN_CONFIG_ID = 1L;

    public CodeGenServiceImpl(TemplateFactory templateFactory) {
        this.templateFactory = templateFactory;
    }

    @Override
    public CodeGenVo getModel(Long id) {
        CodeGenVo codeGenVo = codeGenMapper.getModel(id);
        return codeGenVo;
    }

    @Override
    public Long save(CodeGenRequest userPo) {
        codeGenMapper.save(userPo);
        return userPo.getId();
    }

    @Override
    public Long update(CodeGenRequest userPo) {
        codeGenMapper.update(userPo);
        return userPo.getId();
    }

    @Override
    public List<CodeGenVo> listPage(ParamReq<CodeGenRequest> req) {
        return codeGenMapper.listPage(req);
    }

    @Override
    public Integer countPage(ParamReq<CodeGenRequest> params) {
        return codeGenMapper.countPage(params);
    }


    @Override
    public Integer updateDelFlagById(Long id, Integer delFlag) {
        return codeGenMapper.updateDelFlagById(id, delFlag);
    }

    @Override
    public Result<Integer> createCodeGen(CodeGenRequest codeGenPo) throws TemplateException, IOException {
        Integer count = 0;
        codeGenMapper.deleteByDatasourceNameAndTableName(codeGenPo.getDatasourceName(), codeGenPo.getTableName());
        codeGenMapper.save(codeGenPo);

        initMap(codeGenPo);
        CodeGenConfigPo configPo = getCodeGenConfig();
        templateFactory.createTemplate(codeGenPo, configPo);

        return Result.success(count);
    }

    private void initMap(CodeGenPo codeGen) {
        List<Map<String, Object>> columns = codeGenMapper.listColumnsByDatabaseAndTable(codeGen.getDatasourceName(), codeGen.getTableName());
        codeGen.setColumns(columns);
        codeGen.setLowerEntityName(StrUtil.lowerFirst(codeGen.getEntityName()));
        if (ObjectUtil.isNotEmpty(codeGen.getPackageName())) {
            String[] packages = codeGen.getPackageName().split("\\.");
            codeGen.setLastPackageName(packages[packages.length - 1]);
        }
    }

    /**
     * 得到配置文件
     *
     */
    private CodeGenConfigPo getCodeGenConfig() {
        return codeGenConfigMapper.getModel(CODE_GEN_CONFIG_ID);
    }
}
